package com.jcli.novel_p;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;

import java.io.*;
import java.util.*;

/**
 * 1.0往properties文件写入数据的功能
 * 1.用Java实现，往properties文化中写入数据，格式是中国=China，美国=鹰国，日本=鱼国，如果数据已经存在，则跳过，不存在则新增。
 * 2.并且提示新增了几个，一共几个
 * 3.并提示开始有几个数据,在读取属性文件之前获取属性的初始大小
 * 4. 将要添加的数据使用scanner方法并且改为死循环实现
 * 5.添加：如果输入的值已经存在，但是键不一样；提示是否录入已有的键值对，yes录入，no不录入，用户选择后需要有提示，录入则在现有的键值对中新加键，
 * -.添加：如果输入的键已经存在，则不录入
 * 7.更改规则：首先，键已经存在，则不录入。然后 ，值已经存在，键不一样，则提示是否录入。最后，properties文件中的数据按照值进行排序。
 * -.排序使用冒泡排序实现
 * -.更改：排序按照26个字母的顺序进行排序
 * -.properties文件中的数据按照值进行排序，排序按照26个字母的顺序进行排序
 * 8.properties文件中的数据按照值进行中文多音字排序，使用pinyin4j库。
 *  --排序未实现，待后续操作研究 。
 *  -.开始显示所有的键值对，结尾显示所有的键值对。
 *  9.在用户开始操作之前显示所有键值对，操作结束之后也显示所有键值对。
 * 10.未进行优化
 *
 */

public class WriteToProperties01 {
    public static void main(String[] args) {
        Properties properties = new Properties();
        int addedCount = 0; // 用于跟踪新增数据的计数器

        try (InputStream inputStream = new FileInputStream("src/main/resources/config.properties")) {
            properties.load(new InputStreamReader(inputStream, "UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 打印初始的所有键值对
        System.out.println("初始的键值对:");
        for (Object key : properties.keySet()) {
            System.out.println(key + "=" + properties.getProperty((String) key));
        }

        Scanner scanner = new Scanner(System.in);

        while (true) {
            int initialSize = properties.size();//获取初始属性数量。
            System.out.print("请输入要添加的数据 (格式：键=值)，或输入 'exit' 退出： ");
            String input = scanner.nextLine().trim();

            if (input.equalsIgnoreCase("exit")) {
                break;
            }

            String[] keyValue = input.split("=");
            if (keyValue.length != 2) {
                System.out.println("输入格式无效，请重新输入。");
                continue;
            }

            //5.新增
            String key = keyValue[0];
            String value = keyValue[1];

            if (properties.containsKey(key)) {
                // 如果键已经存在，则不录入
                System.out.println("键 '" + key + "' 已存在，跳过该项。");
            } else if (properties.containsValue(value)) {
                // 查找是否已有相同的值
                Set<String> keys = properties.stringPropertyNames();
                boolean valueExistsWithDifferentKey = false;

                for (String existingKey : keys) {
                    if (properties.getProperty(existingKey).equals(value) && !existingKey.equals(key)) {
                        valueExistsWithDifferentKey = true;
                        break;
                    }
                }

                if (valueExistsWithDifferentKey) {
                    System.out.println("值 '" + value + "' 已存在，但键不同。");
                    System.out.print("是否录入已有的键值对？(yes/no): ");
                    String choice = scanner.nextLine().trim().toLowerCase();
                    if (choice.equals("yes")) {
                        properties.setProperty(key, value);
                        System.out.println("键 '" + key + "' ='" + value + "' 已录入成功。");
                    } else {
                        System.out.println("已跳过键 '" + key + "' 的录入。");
                    }
                } else {
                    System.out.println("值 '" + value + "' 已存在，但键相同，跳过该项。");
                }
            } else {
                properties.setProperty(key, value);
                addedCount++; // 增加计数器
                System.out.println("键 '" + key + "' ='" + value + "' 已录入成功。");
            }


            // 排序并按照值进行中文多音字排序
            List<Map.Entry<Object, Object>> entryList = new ArrayList<>(properties.entrySet());
            entryList.sort(new PinyinComparator());


            try (OutputStream outputStream = new FileOutputStream("src/main/resources/config.properties")) {
                Properties sortedProperties = new Properties();
                for (Map.Entry<Object, Object> entry : entryList) {
                    sortedProperties.setProperty((String) entry.getKey(), (String) entry.getValue());
                }
                sortedProperties.store(new OutputStreamWriter(outputStream, "UTF-8"), null);
                int finalSize = sortedProperties.size(); // 获取最终属性数量
                System.out.println("开始有 " + initialSize + " 个数据，新增了 " + addedCount + " 个数据，总共有 " + finalSize + " 个数据。");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 打印最终的所有键值对
        System.out.println("最终的键值对:");
        for (Object key : properties.keySet()) {
            System.out.println(key + "=" + properties.getProperty((String) key));
        }

        scanner.close();
    }

    // 自定义比较器用于按照中文多音字的拼音排序
    static class PinyinComparator implements Comparator<Map.Entry<Object, Object>> {
        private final HanyuPinyinOutputFormat format;

        public PinyinComparator() {
            format = new HanyuPinyinOutputFormat();
            format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
            format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
            format.setVCharType(HanyuPinyinVCharType.WITH_V);
        }

        @Override
        public int compare(Map.Entry<Object, Object> entry1, Map.Entry<Object, Object> entry2) {
            String value1 = (String) entry1.getValue();
            String value2 = (String) entry2.getValue();
            String pinyin1 = getPinyin(value1);
            String pinyin2 = getPinyin(value2);
            return pinyin1.compareTo(pinyin2);
        }

        private String getPinyin(String chinese) {
            StringBuilder pinyin = new StringBuilder();
            for (char c : chinese.toCharArray()) {
                try {
                    String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
                    if (pinyinArray != null && pinyinArray.length > 0) {
                        pinyin.append(pinyinArray[0]);
                    } else {
                        pinyin.append(c);
                    }
                } catch (Exception e) {
                    pinyin.append(c);
                }
            }
            return pinyin.toString();
        }
    }
}
